/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.client.assembler.output.p10;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import fr.generali.accueilclient.client.om.IAdresse;
import fr.generali.accueilclient.client.om.IPersonne;
import fr.generali.accueilclient.client.om.IPersonneMorale;
import fr.generali.accueilclient.client.om.IPersonnePhysique;
import fr.generali.accueilclient.client.om.NaturePersonne;
import fr.generali.accueilclient.client.om.impl.Adresse;
import fr.generali.accueilclient.client.om.impl.ClientAssociation;
import fr.generali.accueilclient.client.om.impl.ClientAutre;
import fr.generali.accueilclient.client.om.impl.ClientCollectivite;
import fr.generali.accueilclient.client.om.impl.ClientCopropriete;
import fr.generali.accueilclient.client.om.impl.ClientEntreprise;
import fr.generali.accueilclient.client.om.impl.ClientParticulier;
import fr.generali.accueilclient.client.om.impl.ClientProfessionnel;
import fr.generali.accueilclient.utils.stringbuilder.StringBuilderUtils;
import fr.generali.refservcommuns.clients.resume.dto.v3.ctr.structurecontrat.DTOContrat;
import fr.generali.refservcommuns.rce.recherche.nonqualifie.ctc.gestioncontacts.DTOAdresseResume;
import fr.generali.refservcommuns.clients.resume.rechercheparidentifiantnonqualifieservice.v4.ctr.structurecontrat.DtoContrat;
import fr.generali.refservcommuns.rce.recherche.nonqualifie.pty.personnes.DTOPersonneMorale;
import fr.generali.refservcommuns.rce.recherche.nonqualifie.pty.personnes.DTOPersonnePhysique;
import fr.generali.refservcommuns.rce.recherche.nonqualifie.pty.personnes.DTOPersonneResume;

/**
 * Transforme un {@link DTOContrat} en {@link IPersonne}
 * 
 * @author selrhazala
 */
@Component("dtoContrat2PersonneConverter")
public class DTOContrat2PersonneConverter implements Converter<DtoContrat, IPersonne> {

    /**
     * LOGGER
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(DTOContrat2PersonneConverter.class);

    /**
     * Assembler de personne physique
     */
    @Autowired
    @Qualifier("dtoPersonnePhysiqueResume2PersonnePhysiqueConverter")
    private Converter<DTOPersonnePhysique, IPersonnePhysique> dtoPersonnePhysiqueResume2PersonnePhysiqueConverter;

    /**
     * Assembler de personne morale
     */
    @Autowired
    @Qualifier("dtoPersonneMoraleResume2PersonneMoraleConverter")
    private Converter<DTOPersonneMorale, IPersonneMorale> dtoPersonneMoraleResume2PersonneMoraleConverter;

    /**
     * {@inheritDoc}
     */
    public IPersonne convert(DtoContrat input) {
        LOGGER.debug("assemble");
        
        List<DTOPersonneResume> listDTOPersonneResume = input.getRolePersonne();
        DTOPersonneResume dtoPersonneResume = null;
        DTOPersonnePhysique personnePhysique = null;
        DTOPersonneMorale personneMorale = null;
        List<DTOAdresseResume> adresses = null;
            
        if (CollectionUtils.isNotEmpty(listDTOPersonneResume)) {
            dtoPersonneResume = listDTOPersonneResume.get(0);
            personnePhysique = dtoPersonneResume.getDTOPersonnePhysique();
            personneMorale = dtoPersonneResume.getDTOPersonneMorale();
            adresses = dtoPersonneResume.getAdresse();
        }
        
        boolean isPersonnePhysique = personneMorale == null && personnePhysique != null;
        boolean isPersonneMorale = personneMorale != null;
        NaturePersonne nature = NaturePersonne.PARTICULIER;
        if (isPersonnePhysique && personnePhysique.getParticulierProfessionnel() != null
                        && !personnePhysique.getParticulierProfessionnel().isEmpty()) {
            nature = NaturePersonne.PROFESSIONNEL;
        } else {
            if (isPersonneMorale) {
                nature = NaturePersonne.getNaturePersonneFromValue(personneMorale.getTypePersonneMorale());
            }
        }

        IPersonne client = buildClient(nature);
        client.setNumeroClient(dtoPersonneResume.getIdentifiantRCE());
        client.setTypeClient(input.getStatut());
        client.setAdressePrincipale(getAdressePrincipale(adresses));
        client.setActif(true);

        if (NaturePersonne.PARTICULIER.equals(nature) || NaturePersonne.PROFESSIONNEL.equals(nature)) {
            // Récupération des informations du niveau IPersonnePhysique
            IPersonnePhysique.class.cast(client).setPersonnePhysique(
                            dtoPersonnePhysiqueResume2PersonnePhysiqueConverter.convert(personnePhysique));
        } else {
            // Récupération des informations du niveau IPersonneMorale
            IPersonneMorale.class.cast(client).setPersonneMorale(
                            dtoPersonneMoraleResume2PersonneMoraleConverter.convert(personneMorale));
        }

        return client;
    }

    /**
     * @param nature la nature personne
     * @return une personne
     */
    private IPersonne buildClient(NaturePersonne nature) {
        IPersonne client;
        switch (nature) {
            case PARTICULIER:
                client = new ClientParticulier();
                break;
            case PROFESSIONNEL:
                client = new ClientProfessionnel();
                break;
            case ASSOCIATION:
                client = new ClientAssociation();
                break;
            case COLLECTIVITE:
                client = new ClientCollectivite();
                break;
            case COPROPRIETE:
                client = new ClientCopropriete();
                break;
            case ENTREPRISE:
                client = new ClientEntreprise();
                break;
            default:
                client = new ClientAutre();
                break;
        }
        return client;
    }

    /**
     * Récupère l'adresse principale
     * 
     * @param adresses l'adresse
     * @return une personne
     */
    private IAdresse getAdressePrincipale(List<DTOAdresseResume> adresses) {
        IAdresse adresse = null;
        
        if (CollectionUtils.isNotEmpty(adresses)) {
            adresse = new Adresse();
            DTOAdresseResume dtoAdresseResume = adresses.get(0);
            
            if (dtoAdresseResume.getIdentifiant() != null) {
                adresse.setIdentifiant(dtoAdresseResume.getIdentifiant());
            }
            
            if (dtoAdresseResume.getIdentifiant() != null) {
                adresse.setIdentifiant(dtoAdresseResume.getIdentifiant());
            }
        
            adresse.setMotifNpai((dtoAdresseResume.getInfoNPAI() == null 
                            || StringUtils.isEmpty(dtoAdresseResume.getInfoNPAI().getMotifNpai())) 
                            ? null : dtoAdresseResume.getInfoNPAI().getMotifNpai());
            adresse.setBoitePostale(dtoAdresseResume.getLigne5());
            adresse.setCodePays(dtoAdresseResume.getPays());
            adresse.setCodePostal(dtoAdresseResume.getCodePostale());
            // adresse.setPointGeographique(dtoAdresseResume.getLigne4());
            adresse.setPointGeographique(dtoAdresseResume.getComplementIdentiteDestinataire());
            adresse.setPointRemise(dtoAdresseResume.getLigne3());
//            adresse.setQualiteOccupation(dtoAdresseResume.getNatureOccupant());
//            adresse.setTypeLogement(dtoAdresseResume.getTypeBatiment());
            StringBuilder ville = new StringBuilder("");
            if (dtoAdresseResume.getLocalite() != null) {
                ville.append(dtoAdresseResume.getLocalite());
            }
            if (dtoAdresseResume.getCedex() != null) {
                ville.append(StringBuilderUtils.SEPARATOR_ESPACE);
                ville.append(dtoAdresseResume.getCedex());
            }
            adresse.setVille(ville.toString());
//            adresse.setNumeroVoie(dtoAdresseResume.getNumeroRue());
            StringBuilder voie = new StringBuilder("");
            if (dtoAdresseResume.getNumeroRue() != null) {
                voie.append(dtoAdresseResume.getNumeroRue());
                voie.append(StringBuilderUtils.SEPARATOR_ESPACE);
            }
            if (dtoAdresseResume.getExtensionNumeroRue() != null) {
                voie.append(dtoAdresseResume.getExtensionNumeroRue());
                voie.append(StringBuilderUtils.SEPARATOR_ESPACE);
            }
            if (dtoAdresseResume.getTypeRue() != null) {
                voie.append(dtoAdresseResume.getTypeRue());
                voie.append(StringBuilderUtils.SEPARATOR_ESPACE);
            }
            if (dtoAdresseResume.getNomRue() != null) {
                voie.append(dtoAdresseResume.getNomRue());
            }
            adresse.setVoie(voie.toString());
        
        }
        
        return adresse;
    }
}
